package com.zhu.rpc.client;

import com.zhu.rpc.RemoteBean;
import com.zhu.rpc.RpcMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import java.util.Set;

//扫描rpc消费者服务类 并实现动态代理
public class RpcBeanScanner extends ClassPathBeanDefinitionScanner {
    private Logger logger = LoggerFactory.getLogger(RpcBeanScanner.class);
    public RpcBeanScanner(BeanDefinitionRegistry registry) {
        super(registry);
    }

    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
        for (BeanDefinitionHolder holder : beanDefinitions) {

            GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
            Class originCls;
            try {
                originCls = Class.forName(definition.getBeanClassName());
            } catch (ClassNotFoundException e) {
                logger.error("originCls 初始化错误{}",definition.getBeanClassName());
                continue;
            }
            assert originCls != null;
            if (originCls.getAnnotation(RemoteConsumer.class) !=null){
                //消费者动态代理
//                definition.getMetadataAttribute("com.zhu.rpc.RpcClientBean");
                RpcRequest.setMethodCallType(originCls);
                definition.setBeanClass(RpcFactoryBean.class);
                definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
                definition.getPropertyValues().add("cls",originCls);
                this.getRegistry().registerBeanDefinition(holder.getBeanName(), definition);
            }else if (originCls.getAnnotation(RemoteBean.class) !=null){
                //jsonBean
                RemoteBean remoteBean = (RemoteBean) originCls.getAnnotation(RemoteBean.class);
                String beanName = remoteBean.name();
                if ("".equals(beanName)){
                    beanName = originCls.getSimpleName();
                }
                RpcMethod.remoteBeanMap.put(beanName,originCls);
            }

        }
        return beanDefinitions;
    }

    @Override
    protected void registerDefaultFilters() {
        this.addIncludeFilter((metadataReader, metadataReaderFactory) ->
                metadataReader.getAnnotationMetadata().hasAnnotation("com.zhu.rpc.client.RemoteConsumer")||metadataReader.getAnnotationMetadata().hasAnnotation("com.zhu.rpc.RemoteBean"));
    }

    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface()||beanDefinition.isSingleton();
    }
}